﻿package igz.fleaxy.ui.scrollbar
{
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import igz.fleaxy.ui.LinkUi;
	import igz.fleaxy.util.ObjectUtil;

	/**
	 * @author Intelygenz | www.intelygenz.com
	 */
	public class ScrollBarV extends ScrollBarAbstract {
		
		private const _DIRECTION_UP   : Boolean = false;
		private const _DIRECTION_DOWN : Boolean = true;
		
		private var _BtnUp   : LinkUi;
		private var _BtnDown : LinkUi;

		/**
		 * Barra de scroll vertical
		 *
		 * @param	p_scrollContainerUi Contenedor scroll que controlará
		 * @param	p_styles 	: { backgroundStyle : "scrollbarBg", markStyle : "scrollbarMark" }
		 * @param	p_settings {
		 * 				// backgroundStyle
						  "bgSize" : 10
						, "bgColor"	: 0xCBCBCB
						, "bgRound"	: [0, 0, 0, 0]
						, "bgAlpha"	: 1
						, "bgFilters" : []
						, "bgBorder" : null //Color del borde
						, "bgBorderAlpha" : 1
						, "bgBorderThickness" : 0
						// markStyle
						, "markSize" : 10
						, "markColor" : 0x0000FF
						, "markRound" : [0, 0, 0, 0]
						, "markAlpha" : 1
						, "markFilters" : []
						, "markBorder" : null //Color del borde
						, "markBorderAlpha" : 1
						, "markBorderThickness" : 0
						// other settings
						, "size" : null // Tamaño de la barra de scroll
						, "cssName" : null
						, "alwaysVisible" : false
						, "showArrows" : false
				        };
		 * @example
		 *
		 * var container:ScrollContainerUi = new ScrollContainerUi();
		 * var scrollH:ScrollBarH = new ScrollBarH(container
		 * 										, {"backgroundStyle":"scrollbarBg","markStyle":"scrollbarMark"}
		 * 										,{"showArrows":true,"alwaysVisible":true}
		 * 										);
		 *
		 * En la CSS por defecto:
		 * 	.scrollbarBg {
		 * 		igz-color: #212121;
		 * 		igz-round: 0,0,0,0;
		 * 		igz-size: 8;
		 *  }
		 *
		 *  .scrollbarMark {
		 * 		igz-color: #CBCBCB;
		 * 		igz-round: 0,0,0,0;
		 * 		igz-size: 10;
		 * 	}
		 */
		public function ScrollBarV( p_scrollContainerUi:ScrollContainerUi, p_styles:Object = null, p_settings:Object = null ) {
			super( p_scrollContainerUi, p_styles, p_settings );
			
			ObjectUtil.$Merge(p_settings, _Settings);
			
			if ( _Settings["showArrows"] ) {
				_CreateArrowButtons();
				
				_TimerMove.addEventListener(TimerEvent.TIMER, _TimerMove_OnTimer);
			}
			
			_Draw();
		}

		override protected function _Draw() : void {
			this.visible = _Settings["alwaysVisible"];

			var bgHeight:Number;
			if ( _Settings["showArrows"] ) {
				var buttonsSize : Number = _Settings["bgSize"] * 2;
				bgHeight =  _Settings["size"] == null ? _ScrollContainer.height -  buttonsSize: _Settings["size"] - buttonsSize;
				_Bg.y = _Settings["bgSize"];
				_BtnDown.y = bgHeight + _Settings["bgSize"];
				_Mark.y = _Settings["bgSize"];
			}
			else {
				bgHeight = _Settings["size"] == null ? _ScrollContainer.height : _Settings["size"];
			}

			_Bg.graphics.clear();
			_Bg.graphics.beginFill(_Settings["bgColor"], _Settings["bgAlpha"]);
			if ( _Settings["bgBorder"] != null && _Settings["bgBorderThickness"] > 0 ) {
				_Bg.graphics.lineStyle(_Settings["bgBorderThickness"], _Settings["bgBorder"], _Settings["bgBorderAlpha"], true);
			}
			var marginBorder : Number = _Settings["bgBorderThickness"] / 2;
			_Bg.graphics.drawRoundRectComplex( marginBorder
											 , marginBorder
											 , _Settings["bgSize"] - _Settings["bgBorderThickness"]
											 , bgHeight - _Settings["bgBorderThickness"]
											 , _Settings["bgRound"][0], _Settings["bgRound"][1]
											 , _Settings["bgRound"][2], _Settings["bgRound"][3]
											 );
			_Bg.graphics.endFill();

			_Mark.graphics.clear();
			if ( Math.floor(_ScrollContainer.$Container.height) > _ScrollContainer.height ) {
				_Mark.graphics.beginFill( _Settings["markColor"], _Settings["markAlpha"] );
				var markHeight : Number = (_ScrollContainer.height * _Bg.height) / _ScrollContainer.$Container.height;

				if ( _Settings["markBorder"] != null && _Settings["markBorderThickness"] > 0 ) {
					_Mark.graphics.lineStyle(_Settings["markBorderThickness"], _Settings["markBorder"], _Settings["markBorderAlpha"], true);
				}
				marginBorder = _Settings["markBorderThickness"] / 2;
				_Mark.graphics.drawRoundRectComplex(  marginBorder
													, marginBorder
													, _Settings["markSize"] - _Settings["markBorderThickness"]
													, markHeight - _Settings["markBorderThickness"]
													, _Settings["markRound"][0], _Settings["markRound"][1]
													, _Settings["markRound"][2], _Settings["markRound"][3]
													);
				_Mark.graphics.endFill();

				_Mark.x = (_Settings["bgSize"] - _Settings["markSize"]) / 2;
				//_Mark.y = _Bg.y;
				_Mark.y = Math.abs( (_ScrollContainer.$Container.y * _Bg.height) / _ScrollContainer.$Container.height ) + _Bg.y;

				if ( _Mark.y + _Mark.height > _Bg.y + _Bg.height ) {
					//_Mark.y -= (_Mark.y + _Mark.height) - (_Bg.y + _Bg.height);
					_SetMarkY(_ScrollContainer.$Container.height);
				}
				this.visible = true;
				_Bg.addEventListener(MouseEvent.MOUSE_DOWN, _Bg_MouseDown);
			}
			else {
				_SetMarkY( 0 );
				_Bg.removeEventListener(MouseEvent.MOUSE_DOWN, _Bg_MouseDown);
			}

			if ( _Settings["autoPos"] ) {
				this.x = _ScrollContainer.x + _ScrollContainer.width;
				this.y = _ScrollContainer.y;
			}

			_CheckArrowButtons();
		}
		
		private function _CheckArrowButtons () : void {
			if ( _Settings["showArrows"] ) {
				if ( Math.floor(_ScrollContainer.$Container.height) > _ScrollContainer.height ) {
					if ( _Mark.y <= _Bg.y ) {
						_BtnUp.$Disable();
						_BtnDown.$Enable();
						_StopMove();
					}
					else if ( (_Mark.y + _Mark.height) >=  (_Bg.y + _Bg.height) ) {
						_BtnUp.$Enable();
						_BtnDown.$Disable();
						_StopMove();
					}
					else {
						_BtnUp.$Enable();
						_BtnDown.$Enable();
					}
				}
				else {
					_BtnDown.$Disable();
					_BtnUp.$Disable();
				}
			}
		}

		private function _SetMarkY( p_y:Number ) : void {

			var y : Number = p_y;
			if ( y > _Bg.y
			  && y < _Bg.y + _Bg.height - _Mark.height
			)
			{
				_Mark.y = y;
			}
			else if ( y < _Mark.y ) {
				_Mark.y = _Bg.y;
			}
			else if ( y > _Mark.y ) {
				_Mark.y = _Bg.y + _Bg.height - _Mark.height;
			}

			y = -(((_Mark.y-_Bg.y) * _ScrollContainer.$Container.height) / _Bg.height);
			if ( isNaN(y) ) {
				y = 0;
			}
			_ScrollContainer.$Container.y = y;
			
			_CheckArrowButtons();
		}

		override protected function _Mark_MouseMove (p_mouseEvent: MouseEvent) : void {
			_SetMarkY( p_mouseEvent.stageY - _Mark_OffsetY );
		}

		override protected function _ScrollContainer_MouseWheel (p_mouseEvent: MouseEvent) : void {
			p_mouseEvent.stopPropagation();
			if ( Math.floor(_ScrollContainer.$Container.height) > _ScrollContainer.height ) {
				_SetMarkY( _Mark.y - (p_mouseEvent.delta * 2) );
			}
		}
		
		private function _Bg_MouseDown(p_mouseEvent:MouseEvent):void {
			p_mouseEvent.stopPropagation();

			var newMarkY : Number = p_mouseEvent.localY + _Bg.y;
			if ( newMarkY > _Mark.y ) {
				newMarkY -= _Mark.height;
			}
			_SetMarkY( newMarkY );
		}
		
		//
		// Botones de dirección
		//
		private function _CreateArrowButtons () : void {
			var size : Number = _Settings["bgSize"];
			var marginX : Number = size / 5;
			var marginY : Number = size / 3;
			
			// Draw Up Arrow
			var shapeUp :Shape = _CreateArrowButtonBg();
			shapeUp.graphics.beginFill(_Settings["markBorder"]);
			shapeUp.graphics.moveTo( size/2, marginY );
			shapeUp.graphics.lineTo( size-marginX, size-marginY );
			shapeUp.graphics.lineTo( marginX, size-marginY );
			shapeUp.graphics.lineTo( size / 2, marginY );
			shapeUp.graphics.endFill();
			
			// Draw Down Arrow
			var shapeDown :Shape = _CreateArrowButtonBg();
			shapeDown.graphics.beginFill(_Settings["markBorder"]);
			shapeDown.graphics.moveTo( marginX, marginY );
			shapeDown.graphics.lineTo( size / 2, size-marginY );
			shapeDown.graphics.lineTo( size-marginX, marginY );
			shapeDown.graphics.lineTo( marginX, marginY );
			shapeDown.graphics.endFill();
			
			_BtnUp = new LinkUi( shapeUp, { "onMouseDown": _BtnUp_OnMouseDown
											, "onMouseUp": _BtnUp_OnMouseUp
											, "onRollOut": _BtnUp_OnRollOut }
								);
			addChild( _BtnUp );
			
			_BtnDown = new LinkUi( shapeDown, { "onMouseDown": _BtnDown_OnMouseDown
												, "onMouseUp": _BtnDown_OnMouseUp
												, "onRollOut": _BtnDown_OnRollOut }
								);
			addChild( _BtnDown );
		}

		private function _BtnUp_OnMouseDown ( p_mouseEvent:MouseEvent ) : void {
			_MoveDirection = _DIRECTION_UP;
			_Up();
			_TimerStartMove.start();
		}
		private function _BtnUp_OnMouseUp ( p_mouseEvent:MouseEvent ) : void {
			_StopMove();
		}
		private function _BtnUp_OnRollOut ( p_mouseEvent:MouseEvent ) : void {
			_StopMove();
		}

		private function _BtnDown_OnMouseDown ( p_mouseEvent:MouseEvent ) : void {
			_MoveDirection = _DIRECTION_DOWN;
			_Down();
			_TimerStartMove.start();
		}
		private function _BtnDown_OnMouseUp ( p_mouseEvent:MouseEvent ) : void {
			_StopMove();
		}
		private function _BtnDown_OnRollOut ( p_mouseEvent:MouseEvent ) : void {
			_StopMove();
		}

		private function _TimerMove_OnTimer( p_timerEvent:TimerEvent ):void {
			if ( _MoveDirection == _DIRECTION_UP ) {
				_Up();
			}
			else {
				_Down();
			}
		}

		private function _Down() : void {
			_SetMarkY( _Mark.y + _Settings["scrollSpeed"] );
		}

		private function _Up():void {
			_SetMarkY( _Mark.y - _Settings["scrollSpeed"] );
		}
	}
	
}